import logging
import random

from django.http import JsonResponse, HttpResponse
from django.views import View
from django_redis import get_redis_connection

from celery_task.tasks.sms import ccp_send_sms_code
from meiduo.libs.captcha.captcha import Captcha

logger = logging.getLogger('django')


# Create your views here.

class ImageCodeView(View):

    def get(self, request, uuid):
        """
        uuid验证码图片获取
        :param request: 请求对象
        :param uuid: 16进制uuid，由浏览器生成的唯一编号
        :return: 验证码图片
        """
        img_code, img_data = Captcha.instance().generate_captcha()  # 获取验证码及图片二进制数据
        print(f"图形验证码：{img_code}")
        redis_conn = get_redis_connection('verify_code')  # 根据django的缓存配置中的"verify_code"获取redis客户端对象
        try:
            redis_conn.setex(f'img_code_{uuid}', 300, img_code)  # 存储验证码并设置有效期为5分钟，以供后续验证
        except Exception as e:
            logger.error(f'图片验证码存储失败：{e}')
        return HttpResponse(img_data, content_type='image/jpg')  # 返回验证码图片


class SMSCodeView(View):

    def get(self, request, mobile):
        """
        获取短信验证码
        :param request: 请求对象
        :param mobile: 手机号
        :return: JSON
        """
        '''获取数据'''
        image_code = request.GET.get("image_code")  # 获取用户输入的验证码
        image_code_id = request.GET.get("image_code_id")  # 获取验证码图片的唯一编号
        redis_conn = get_redis_connection("verify_code")  # 根据django的缓存配置中的"verify_code"获取redis客户端对象

        '''比对图片验证码'''
        img_check_code = redis_conn.get(f"img_code_{image_code_id}")  # 获取数据库中的图片验证码
        if not img_check_code:  # 判断验证码是否有效
            return JsonResponse({'code': 400, 'errmsg': '图片验证码过期'})
        if image_code.upper() != img_check_code.decode().upper():  # 验证码有效则进一步验证用户输入的验证码
            return JsonResponse({'code': 400, 'errmsg': '图片验证码错误'})
        # redis_conn.delete(f"img_code_{image_code_id}")  # 验证通过之后删除数据库中的图片验证码信息

        '''发送短信验证码'''
        if redis_conn.get("sms_sent_flag"):  # 验证短信发送标志是否有效，防止恶意重复发送验证码
            return JsonResponse({'code': 400, 'errmsg': '请勿频繁发送短信验证码'})
        sms_code = "%06d" % random.randint(0, 999999)  # 生成6位数随机验证码
        print(f"短信验证码：{sms_code}")
        pip = redis_conn.pipeline()  # 获取一个管道对象
        try:
            pip.setex(f"sms_code_{mobile}", 300, sms_code)  # 存储验证码信息并设置有效期5分钟，以供后续验证
            pip.setex("sms_sent_flag", 60, "1")  # 为防止频繁发送验证码，同时设置一个60秒有效的标志
            pip.execute()  # 通过管道批量执行redis指令
        except Exception as e:
            logger.error(f"数据库操作失败：{e}")
        ccp_send_sms_code.delay(mobile, [sms_code, 5], 1)  # 发布异步任务（需先启动异步任务捕获），向目标手机发送随机6位数短信验证码

        '''构建发送成功响应'''
        return JsonResponse({'code': 0, 'errmsg': 'OK'})
